# coding:UTF-8
import numpy as np
# from sklearn import datasets

def sig(x):
    '''
    Sigmoid函数
    :param x: s(mat):feature * w
    :return: sigmoid(x)(mat):Sigmoid值
    '''
    return 1.0/(1+np.exp(-x))

def lr_train_bgd(feature, label, maxCycle, alpha):
    '''
    利用梯度下降法训练LR模型
    :param feature: 特征
    :param label: 标签
    :param maxCycle: 最大迭代次数
    :param alpha: 学习率
    :return: 权重
    '''
    #特征个数
    n = np.shape(feature)[1]
    #初始化权重
    w = np.mat(np.ones((n, 1)))
    i = 0
    #最大迭代次数的范围内
    while i < maxCycle:
        #当前迭代次数
        i += 1
        #计算sigmoid值
        h = sig(feature * w)
        err = label - h
        if i % 100 == 0:
            print("\t------iter=" + str(i) + \
                " , train error rate= " + str(error_rate(h, label)))
        #修正权重
        w = w +alpha * feature.T * err
    return w

def error_rate(h, label):
    '''
    计算当前损失函数值
    :param h: 预测值
    :param label: 实际值
    :return: err/m(float):错误率
    '''
    m = np.shape(h)[0]
    sum_err = 0.0
    for i in range(m):
        if h[i, 0] > 0 and (1 - h[i, 0]) > 0:
            sum_err -= (label[1, 0] * np.log(h[i, 0]) + \
                        (1 - label[i, 0]) * np.log(1 - h[i, 0]))
        else:
            sum_err -= 0
    return sum_err / m

def load_data(file_name):
    '''
    :param file_name:训练数据的位置
    :return: feature_data: 特征
        label_data: 标签
    '''
    f = open(file_name)
    feature_data = []
    label_data = []
    for line in f.readlines():
        feature_tmp = []
        label_tmp = []
        lines = line.strip().split("\t")
        # 偏置项
        feature_tmp.append(1)
        for i in range(len(lines) - 1):
            feature_tmp.append(float(lines[i]))
        label_tmp.append(float(lines[-1]))

        feature_data.append(feature_tmp)
        label_data.append(label_tmp)
    f.close()
    return np.mat(feature_data), np.mat(label_data)

def save_model(file_name, w):
    '''
    保存最终的模型
    :param file_name:模型保存的文件
    :param w: LR模型的权重
    '''
    m = np.shape(w)[0]
    f_w = open(file_name, "w")
    w_array = []
    for i in range(m):
        w_array.append(str(w[i, 0]))
    f_w.write("\t".join(w_array))
    f_w.close()

if __name__ == "__main__":
    dir = "/home/xiefeihong/PycharmProjects/SimpleMachineLearning/static/sample/"
    #1. 导入训练数据
    print("------1. load data ------")
    feature, label = load_data(dir + "data.txt")
    #2. 训练LR模型
    print("------2. raining------")
    w = lr_train_bgd(feature, label, 1000, 0.01)
    #3. 保存最终模型
    print("------3. save model------")
    save_model(dir + "weights.txt", w)